package com.tanxi521.tnlevel.dao;

import com.tanxi521.tnlevel.TnLevel;
import com.tanxi521.tnlevel.utils.ConfigReader;
import org.bukkit.ChatColor;

import java.sql.*;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * @Author: i-xiaotian
 * @Date: 2022/3/13 4:25
 * @EMAIL: 1254806967@qq.com
 */
public final class ConnectionPool {

    // 容量20连接池
    public final static ArrayBlockingQueue<Connection> pool =
            new ArrayBlockingQueue<>(ConfigReader.getPoolSize());

    // 初始化连接池Mysql
    public static void initPoolMysql() {
        TnLevel.getInstance().getLogger().info("§2正在初始化连接池");
        try {
            for (int i = 0; i < ConfigReader.getPoolSize(); i++) {
                Connection connection = initConnection();
                pool.add(connection);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TnLevel.getInstance().getLogger().warning("§c数据库连接失败，请检查配置文件");
            TnLevel.getInstance().getServer().getPluginManager().disablePlugin(TnLevel.getInstance());
        }
        TnLevel.getInstance().getLogger().info(ChatColor.GREEN + "初始化连接池成功");
    }

    // 初始化连接池SQLITE
    public static void initPoolSQLITE() {
        try {
            TnLevel.getInstance().getLogger().info("§2正在初始化连接池");
            Class.forName(ConfigReader.getMysqlDriver());
            String databaseName = "tn_level";
            for (int i = 0; i < ConfigReader.getPoolSize(); i++) {
                Connection connection = DriverManager.getConnection("jdbc:sqlite:plugins/TnLevel/" + databaseName + ".db");
                pool.add(connection);
            }
            TnLevel.getInstance().getLogger().info(ChatColor.GREEN + "初始化连接池成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection initConnection() {
        try {
            Class.forName(ConfigReader.getMysqlDriver());
            String url = ConfigReader.getMysqlUrl();
            String mysqlPort = ConfigReader.getMysqlPort();
            String mysqlUser = ConfigReader.getMysqlUser();
            String mysqlPassword = ConfigReader.getMysqlPassword();
            String mysqlDatabase = ConfigReader.getMysqlDatabase();
            String databaseName = "tn_level";
            String mysqlUrl = "jdbc:mysql://" + url + ":" + mysqlPort + "/" + mysqlDatabase +
                    "?useSSL=false&autoReconnect=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8";
            return ConfigReader.getMysqlUse() ? DriverManager.getConnection(mysqlUrl, mysqlUser, mysqlPassword)
                    : DriverManager.getConnection("jdbc:sqlite:plugins/TnLevel/" + databaseName + ".db");
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Connection getConnection() {
        try {
            Connection take = pool.take();
            try (Statement statement = take.createStatement();
                 ResultSet resultSet = statement.executeQuery(SQLStatement.CHECK_CONNECTION.getStatement())) {
                resultSet.next();
                // 连接有效
                return take;
            } catch (SQLException e) {
                // 连接无效或发生异常
                TnLevel.getInstance().getLogger().info("连接无效,重新获取");
                return initConnection();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return initConnection();
    }

    public static void returnSource(Connection connection) {
        try {
            pool.put(connection);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void close(ArrayBlockingQueue<Connection> pool) {
        TnLevel.getInstance().getLogger().info(ChatColor.GREEN + "调取连接池释放");
        long start = System.currentTimeMillis();
        while (true) {
            Connection connection = pool.poll();
            if (connection == null) {
                break;
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        TnLevel.getInstance().getLogger().info(ChatColor.GREEN + "成功释放连接,耗时" +
                (System.currentTimeMillis() - start) + "ms");
    }


}
